package main;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 * MapFrame - handles drawing of map, mouse, keyboard functionality
 * @author 12817152
 *
 */

public class MapFrame extends JFrame {
	static BasicMap bm;
	static MapStatusBar msb;
	static TurnManager turnMgr;
	static MapPanel mp;
	Unit u, target;
	Colony col;
	City city;
	boolean unitSel = false, colSel = false, citySel = false;
	UnitSelector usp;
	boolean uspdead, fight;
	boolean movePicked = false, attacked = false;

	/**
	 * MapFrame constructor creates frame, handles functionality
	 * @param title - frame title
	 * @param basicMap - map
	 * @param player1 - (for now) player
	 * @param player2 - enemy placeholder
	 */
	public MapFrame(String title, BasicMap basicMap, Player player1, Player player2, final TurnManager t, MapPanel mapPanel, final MapStatusBar status) {
		super(title);

		//setting opponents
		player1.setOpponent(player2);
		player2.setOpponent(player1);

		//creating panels/turn managers
		turnMgr = t;
		msb = status;
		bm = basicMap;
		mp = mapPanel;

		setVisible(true); //create frame
		setSize(750, 750);
		setLayout(new BorderLayout());		
		add(mp, BorderLayout.CENTER);
		add(msb, BorderLayout.PAGE_END);

		//increment turns
		status.turn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(t.paused) {
					t.resume();
					status.turn.setText("Complete Turn");
					//System.out.println(t.getTurn());
					status.update();
				} else {
					t.increment();
					status.turn.setText("Next Turn");
					if(unitSel)
						deselectUnit();
				}
			}
		});

		//key listener for popping up frames
		final KeyListeningBandit bandit = new KeyListeningBandit(t, u);
		KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
		manager.addKeyEventDispatcher(bandit);

		//mouse functionality
		mp.addMouseListener(new MouseAdapter() {

			public void mouseClicked(MouseEvent e) {
				//left click, if no unit selected, place new unit
				//otherwise move selected unit to click location

				try {
					try{
						uspdead = usp.dead;
					} catch(NullPointerException ne) {
						uspdead = true;
					}

					if(e.getButton() == e.BUTTON1 && !t.paused && !mp.newGame) {
						if(unitSel && uspdead) {
							target = bm.getLand((int)(e.getX()/(mp.getWidth()/bm.getWidth())), (int)((e.getY())/(mp.getHeight()/bm.getHeight()))).getUnit();

							if(target != null && target.owner == t.inactive) {
								u.Attack(target);
								JOptionPane.showMessageDialog(null, "Enemy Health Remaining: " + target.getCHealth());
							} else if(target != null) {	
								JOptionPane.showMessageDialog(null, "Position occupied, idiot.");
							} else {
								//System.out.println("A" + u.moveDone);
								u.move((int)(e.getX()/(mp.getWidth()/bm.getWidth())), (int)((e.getY())/(mp.getHeight()/bm.getHeight())), bm, t.active, t.inactive);
								mp.repaint();
							}
						} else if(uspdead){
							//usp = new UnitSelector(t.active, bm, mp, (int)(e.getX()/(mp.getWidth()/bm.getWidth())), (int)((e.getY()-22)/(mp.getHeight()/bm.getHeight())), mp.getLocationOnScreen().x+e.getX(), mp.getLocationOnScreen().y+e.getY()-22);
						}
						//right click, if unit selected, deselect unit
						//otherwise select unit (if there is a unit at that location)
					} else if(e.getButton() == e.BUTTON3 || e.getButton() == e.BUTTON2) {
						//System.out.println((int)(e.getX()/(mp.getWidth()/(double)bm.getWidth())) +"," +(int)((e.getY())/(mp.getHeight()/(double)bm.getHeight())));
						
						if(colSel && uspdead) {
							deselectCol();
						} else if(citySel && uspdead) {
							deselectCity();
						} else if(unitSel && uspdead) {
							bandit.updateUnit(null);
							deselectUnit();
						} else if(uspdead) {
							u = bm.getLand((int)(e.getX()/(mp.getWidth()/(double)bm.getWidth())), (int)((e.getY())/(mp.getHeight()/(double)bm.getHeight()))).getUnit();
							col = bm.getLand((int)(e.getX()/(mp.getWidth()/(double)bm.getWidth())), (int)((e.getY())/(mp.getHeight()/(double)bm.getHeight()))).getColony();
							city = bm.getLand((int)(e.getX()/(mp.getWidth()/(double)bm.getWidth())), (int)((e.getY())/(mp.getHeight()/(double)bm.getHeight()))).getCity();
							if (u != null) {
								if(u.owner == t.active) {
									u.setColor(u.getBasicColor().brighter());
									bandit.updateUnit(u);
									unitSel = true;
								}
							} else if(col != null) {
								/*if(col.owner == t.active) {
										col.setColor(col.getOrigColor().brighter());
										colSel = true;
										System.out.println("hEY! yOU");
										if(uspdead)
											usp = new UnitSelector(t.active, bm, mp, (int)(e.getX()/(mp.getWidth()/bm.getWidth())), (int)((e.getY()-22)/(mp.getHeight()/bm.getHeight())), mp.getLocationOnScreen().x+e.getX(), mp.getLocationOnScreen().y+e.getY()-22);
									}*/
							} else if(city != null && city.owner == t.active) {
								city.setCol(city.getOrigCol().brighter());
								citySel = true;
								if(uspdead)
									usp = new UnitSelector(t.active, bm, mp, (int)(e.getX()/(mp.getWidth()/(double)bm.getWidth())), (int)((e.getY())/(mp.getHeight()/(double)bm.getHeight())), mp.getLocationOnScreen().x+e.getX(), mp.getLocationOnScreen().y+e.getY());
							} else {
								new SpawnPanel(t.active, (int)(e.getX()/(mp.getWidth()/(double)bm.getWidth())), (int)((e.getY())/(mp.getHeight()/(double)bm.getHeight())), mp, bm, mp.getLocationOnScreen().x+e.getX(), mp.getLocationOnScreen().y+e.getY());
							}
						}
						mp.repaint();
					}
				} catch(ArrayIndexOutOfBoundsException a) {
					System.err.println("an error. PANIC PANIC PANIC [map out of bounds]");
				}
			}
		});

		//exit on window close
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
			//repaint on gain of focus
			public void windowGainedFocus(WindowEvent e) {
				mp.repaint();
			}
		});

		System.out.println("Good news! No errors! (I mean it) [startup successful]");

	}

	/**
	 * reset color of unit when deselected
	 */
	public void deselectUnit() {
		u.setColor(u.getBasicColor());
		unitSel = false;
	}

	/**
	 * resets color, deselects colonies
	 */
	public void deselectCol() {
		col.setColor(col.getOrigColor());
		colSel = false;
	}

	/**
	 * resets color, deselects city
	 */
	public void deselectCity() {
		city.setCol(city.getOrigCol());
		citySel = false;
	}
}
